home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / du / du.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-09  |  4.0 KB  |  213 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  DU <files/dirs>
  9.  *
  10.  */
  11.  
  12. #include <exec/types.h>
  13. #include <dos/dos.h>
  14. #include <dos/dosextens.h>
  15. #include <clib/dos_protos.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <setjmp.h>
  20. #include <lib/version.h>
  21.  
  22. #define push_jmp(jbuf,jptr) ((jptr = JmpBase), (JmpBase = jbuf), setjmp(jbuf))
  23. #define forget_jmp(jptr)    { JmpBase = jptr; }
  24.  
  25. typedef struct FileInfoBlock    Fib;
  26. typedef struct InfoData     InfoData;
  27.  
  28. typedef struct Accum {
  29.     struct Accum *Parent;
  30.     char    *Name;
  31.     long    Files;
  32.     long    Dirs;
  33.     long    Blocks;
  34. } Accum;
  35.  
  36. char *AccToName(Accum *);
  37. long GetBlockSize(char *);
  38.  
  39. int mybrk(void);
  40. void ScanDir(Accum *, char *, int);
  41.  
  42. #ifdef _DCC
  43. IDENT("du",".03");
  44. DCOPYRIGHT;
  45. #endif
  46.  
  47. long BlockSize;
  48. jmp_buf *JmpBase;
  49.  
  50. main(ac, av)
  51. short ac;
  52. char *av[];
  53. {
  54.     static Accum ac0;
  55.     short i;
  56.     long bytes;
  57.     jmp_buf jbuf;
  58.     jmp_buf *jptr;
  59.  
  60.     onbreak(mybrk);
  61. //    if (push_jmp(jbuf,jptr)) {
  62.     jptr = JmpBase;
  63.     JmpBase = &jbuf;
  64.     if(setjmp(jbuf)) {
  65.     puts("^C");
  66.     exit(1);
  67.     }
  68.  
  69.     if (ac == 1)
  70.     av[ac++] = "";      /*  overwrites the NULL, which is OK    */
  71.  
  72.     bytes = 0;
  73.     for (i = 1; i < ac; ++i) {
  74.     long lastBlocks = ac0.Blocks;
  75.     BlockSize = GetBlockSize(av[i]);
  76.     ScanDir(&ac0, av[i], 0);
  77.     bytes += (ac0.Blocks - lastBlocks) * BlockSize;
  78.     }
  79.     if (ac > 2)
  80.     printf("%-30s %6ld Kb %6ld BLKS\n", "--TOTAL--", bytes / 1024, ac0.Blocks);
  81.     return(0);
  82. }
  83.  
  84. void
  85. ScanDir(acp, name, level)
  86. Accum *acp;
  87. char *name;
  88. int level;
  89. {
  90.     BPTR lock;
  91.     jmp_buf jbuf;
  92.     jmp_buf *jptr;
  93.  
  94.     if (lock = Lock(name, SHARED_LOCK)) {
  95.     __aligned Fib fib;
  96.     Accum acx;
  97.  
  98. //    if (push_jmp(jbuf,jptr)) {
  99.     jptr = JmpBase;
  100.         JmpBase = &jbuf;
  101.         if(setjmp(jbuf)) {
  102.         UnLock(lock);
  103. //        forget_jmp(jptr);
  104.         JmpBase = jptr;
  105.         longjmp(*jptr, 1);
  106.     }
  107.     clrmem(&acx, sizeof(acx));
  108.     acx.Parent = acp;
  109.     acx.Name = name;
  110.  
  111.     memset((char *)&fib,0,sizeof(fib));
  112.     if (Examine(lock, (struct FileInfoBlock *)&fib)) {
  113.         if (fib.fib_DirEntryType > 0) {    /*  dir       */
  114.         long old = CurrentDir(lock);
  115.  
  116. //        forget_jmp(jptr);
  117.         JmpBase = jptr;
  118.  
  119. //        if (push_jmp(jbuf,jptr)) {
  120.         jptr = JmpBase;
  121.             JmpBase = &jbuf;
  122.             if(setjmp(jbuf)) {
  123.             CurrentDir(old);
  124.             UnLock(lock);
  125. //            forget_jmp(jptr);
  126.             JmpBase = jptr;
  127.             longjmp(*jptr, 1);
  128.         }
  129.  
  130.         ++acx.Blocks;
  131.         ++acx.Dirs;
  132.         while (ExNext(lock, (struct FileInfoBlock *)&fib)) {
  133.             if((fib.fib_DirEntryType != ST_LINKDIR)
  134.               && (fib.fib_DirEntryType != ST_LINKFILE)
  135.               && (fib.fib_DirEntryType != ST_SOFTLINK)) {
  136.             ScanDir(&acx, fib.fib_FileName, level + 1);    
  137.               }
  138.               else {
  139.             ++acx.Files;    // show link as a file
  140.             ++acx.Blocks;
  141.               }
  142.         }
  143.         CurrentDir(old);
  144.         Examine(lock, (struct FileInfoBlock *)&fib);
  145.         } else {                /*  link    */
  146.         ++acx.Files;
  147.         acx.Blocks += 1 + fib.fib_NumBlocks + fib.fib_NumBlocks / 72;
  148.         }
  149.     }
  150. //    forget_jmp(jptr);
  151.     JmpBase = jptr;
  152.     UnLock(lock);
  153.     acp->Blocks += acx.Blocks;
  154.     acp->Dirs   += acx.Dirs;
  155.     acp->Files  += acx.Files;
  156.     if (fib.fib_DirEntryType > 0 && level < 2) {
  157.         printf("%*.*s%-*s %6ld Kb %6ld BLKS\n",
  158.         level, level, "",
  159.         30 /* - level */, AccToName(&acx),
  160.         acx.Blocks / 2, acx.Blocks
  161.         );
  162.     }
  163.     }
  164. }
  165.  
  166. char *
  167. AccToName(acp)
  168. Accum *acp;
  169. {
  170.     static char Buf[1024];
  171.     char *ptr = Buf + sizeof(Buf);
  172.  
  173.     *--ptr = 0;
  174.     while (acp && acp->Name) {
  175.     int len = strlen(acp->Name);
  176.     char c = acp->Name[len-1];
  177.  
  178.     if (*ptr && c && c != '/' && c != ':')
  179.         *--ptr = '/';
  180.     ptr -= len;
  181.     strncpy(ptr, acp->Name, len);
  182.     acp = acp->Parent;
  183.     }
  184.     return(ptr);
  185. }
  186.  
  187. int mybrk()
  188. {
  189.     longjmp(*JmpBase, 1);
  190. }
  191.  
  192. long
  193. GetBlockSize(dir)
  194. char *dir;
  195. {
  196.     long lock;
  197.     long lock2;
  198.     long r = 0;
  199.     InfoData id;
  200.  
  201.     if (lock = Lock(dir, SHARED_LOCK)) {
  202.     while (lock2 = ParentDir(lock)) {
  203.         UnLock(lock);
  204.         lock = lock2;
  205.     }
  206.     if (Info(lock, &id))
  207.         r = id.id_BytesPerBlock;
  208.     UnLock(lock);
  209.     }
  210.     return(r);
  211. }
  212.  
  213.